using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Reflection;
using System.Xml;

using MicroFractal.iTunesBrowser.Business;
using MicroFractal.iTunesBrowser.Core.Device;

namespace MicroFractal.iTunesBrowser.Core.Data
{
    public abstract class DbParser
    {

        #region Constructors

        public DbParser(IDevice device, MemoryStream file)
        {
            if (file == null)
                throw new ArgumentNullException("file");

            _file = file;
            _device = device;
        }

        #endregion

        #region Attr

        protected MemoryStream _file;
        protected IDevice _device;

        private static XmlDocument _versions;

        const string K_VersionFile = "iTunesDBVersions.xml";
        const string K_TypeAttr = "type";
        const string K_NameAttr = "name";
        const string K_ParserAttr = "parser";

        #endregion

        #region Methods

        public static DbParser GetDbParser(IDevice device, MemoryStream file)
        {

            string pName = GetDbParserName(file);
            Type t = Assembly.GetExecutingAssembly().GetType(pName);

            if (t == null)
                throw new Exception(); //TODO ver tipo de exception

            if (!t.BaseType.Equals(typeof(DbParser)))
                throw new Exception(); //TODO ver tupo de exception

            DbParser result = t.GetConstructor(new Type[] { typeof(IDevice),typeof(MemoryStream) }).Invoke(new object[] { device, file }) as DbParser;

            return result;
        }

        public abstract Library GetLibrary();

        #endregion

        #region Private Methods

        private static string GetDbParserName(MemoryStream file)
        {
            try
            {
                if (_versions == null)
                {
                    _versions = new XmlDocument();
                    _versions.Load(Path.Combine(AppDomain.CurrentDomain.BaseDirectory,  K_VersionFile));
                }

                int version = Helper.ITunesHelper.BytesToInt(file, 16, 4);

                XmlNode node = _versions.DocumentElement.SelectSingleNode(string.Format("version[@{0}='{1}']", K_TypeAttr, version.ToString()));

                if (node == null)
                    throw new Exception(); //TODO cambiar el tipo de exception

                return node.Attributes[K_ParserAttr].Value;
            }
            catch (Exception )
            {
                return "MicroFractal.iTunesBrowser.Core.Data.ITunesDB.ITunesDBParser";
            }
        }

        #endregion
    }
}
